Skip to content

Comments

Rewrite installer tasks#3

Merged
LexManos merged 8 commits intoMinecraftForge:FD_7.0from
LexManos:isntaller-tasks
Feb 22, 2026
Merged

Rewrite installer tasks#3
LexManos merged 8 commits intoMinecraftForge:FD_7.0from
LexManos:isntaller-tasks

Conversation

@LexManos
Copy link
Member

@LexManos LexManos commented Feb 20, 2026

Re-writes the installer tasks into a grouped system.
Basically drastically reduces the duplicate code (shaves 100 lines off the buildscript), and manages packing all the files as needed by introducing a bunch of helpers. As well as treating the tasks for building the installer jar as a single group.

Shove this into the experimental branch and see what i'm thinking.
Everything i'm doing, should be config cache and lazy config compatible.

forgedev.installer("testInstaller") {
    dev = !forgedev.ci
    offline = false

    // Add extra libraries
    pack tasks.named('serverShimJar', Jar) // The Server executable jar IS needed to be packed, as the installer would need a spec bump in order to download it
    pack tasks.named('universalJar', Jar) // I don't think this is strictly needed to be packed anymore, will need to double check later
    // This isn't actually needed, but its here for some reason, probably wasn't deleted when then installer process was cleaned up
    library mcpArtifactString

    launcherLibrary tasks.named('universalJar', Jar)
    // We configure the launcher here to keep the order for easier diff, after publishing, move this to the LauncherJson configuration below
    launcherJson {
        // We create this during install, so it's not downloadable
        generated(tasks.named('applyClientBinPatches'), 'client')
    }

    launcherLibraries configurations.installerextra
    launcherLibraries configurations.installer

    var launcherId = "${minecraftVersion}-${project.name}-${forgeVersion}"
    var installertools = tool(buildLibs.installertools)
    var renamer = tool(buildLibs.renamer)
    var binarypatcher = tool(buildLibs.binarypatcher)

    jar {
        from(EXTRA_TXTS)
        from(rootProject.file('/forge_installer_logo.png')) {
            rename { 'big_logo.png' }
        }
        from(genClientBinPatches.output) {
            rename { 'data/client.lzma' }
        }
        from(genServerBinPatches.output) {
            rename { 'data/server.lzma' }
        }

        final var argsFile = rootProject.file('server_files/args.txt')
        final Map<String, Map<String, String>> tokens = [tokens: [
            SHIM_JAR_FILE: serverShimJar.archiveFileName.get(),
            MAVEN_PATH: mavenPath
        ]]
        from(argsFile) {
            filter(tokens, ReplaceTokens)
            into 'data'
            rename { 'unix_args.txt' }
        }
        from(argsFile) {
            filter(tokens, ReplaceTokens)
            into 'data'
            rename { 'win_args.txt' }
        }

        from(rootProject.file('server_files')) {
            filter(tokens, ReplaceTokens)
            into 'data'
            exclude 'args.txt'
        }

        jarSigner.sign(it)
    }
    json {
        icon = rootProject.file('icon.ico')
        executable tasks.named('serverShimJar', Jar)
        minecraft = minecraftVersion
        profileVersion = launcherId

        var projectArtifact = "${project.group}:${project.name}:${project.version}"

        data 'MOJMAPS', "[net.minecraft:client:${minecraftVersion}:mappings@tsrg]", "[net.minecraft:server:${minecraftVersion}:mappings@tsrg]"
        data 'MOJMAPS_SHA', downloadClientMappings.output, downloadServerMappings.output

        data 'MC_UNPACKED', "[net.minecraft:client:${minecraftVersion}]", "[net.minecraft:server:${minecraftVersion}:unpacked]"
        data 'MC_UNPACKED_SHA', setupMCP.clientRaw, setupMCP.serverExtracted

        data 'MC_OFF', "[net.minecraft:client:${minecraftVersion}:official]", "[net.minecraft:server:${minecraftVersion}:official]"
        data 'MC_OFF_SHA', createClientOfficial.output, createServerOfficial.output

        data 'BINPATCH', '/data/client.lzma', '/data/server.lzma'
        data 'PATCHED', "[$projectArtifact:client]", "[$projectArtifact:server]"
        data 'PATCHED_SHA', applyClientBinPatches.output, applyServerBinPatches.output

        def rename = (side, input) -> {
            step(renamer) {
                sides = [side]
                args = [
                    '--input', input,
                    '--output', '{MC_OFF}',
                    '--names', '{MOJMAPS}',
                    '--ann-fix', '--ids-fix', '--src-fix', '--record-fix', '--strip-sigs', '--reverse'
                ]
                cache '{MC_OFF}', '{MC_OFF_SHA}'
            }
        }

        steps = [
            extract(installertools) {
                side = 'server'
                archive '{INSTALLER}'
                extract 'data/README.txt', '{ROOT}/README.txt'
                extract 'data/run.sh', '{ROOT}/run.sh'
                executable '{ROOT}/run.sh'
                extract 'data/run.bat', '{ROOT}/run.bat'
                optional 'data/user_jvm_args.txt', '{ROOT}/user_jvm_args.txt'
                extract 'data/unix_args.txt', "{ROOT}/libraries/${mavenPath}/unix_args.txt"
                extract 'data/win_args.txt', "{ROOT}/libraries/${mavenPath}/win_args.txt"
            },
            extractBundle(installertools) {
                side = 'server'
                libraries()
            },
            extractBundle(installertools) {
                side = 'server'
                jar '{MINECRAFT_JAR}', '{MC_UNPACKED}'
                cache '{MC_UNPACKED}', '{MC_UNPACKED_SHA}'
            },
            step(installertools) {
                args = [
                    '--task', 'DOWNLOAD_MOJMAPS',
                    '--sanitize',
                    '--version', minecraftVersion,
                    '--side', '{SIDE}',
                    '--output', '{MOJMAPS}'
                ]
                cache '{MOJMAPS}', '{MOJMAPS_SHA}'
            },
            rename.call('server', '{MC_UNPACKED}'),
            rename.call('client', '{MINECRAFT_JAR}'),
            step(binarypatcher) {
                args = [
                    '--clean', '{MC_OFF}',
                    '--output', '{PATCHED}',
                    '--apply', '{BINPATCH}',
                    '--data', '--unpatched'
                ]
                cache '{PATCHED}', '{PATCHED_SHA}'
            }
        ]
    }

    launcherJson {
        // These are flags to preserve glitchy old behavior to make diffing easier, removing when migrating to production is recommended
        sortLibraries = false // Don't sort, makes things non-deterministic, but easier to diff old versions
        duplicateLibraries = true // Our 'bootstrap' layer go added twice
        librariesLast = false // Makes libraries be added before args

        id = launcherId
        inheritsFrom = minecraftVersion
        mainClass = 'net.minecraftforge.bootstrap.ForgeBootstrap'
        gameArgs = [ '--launchTarget', 'forge_client' ]
        jvmArgs = [ '-Djava.net.preferIPv6Addresses=system' ]
    }
}

@LexManos LexManos marked this pull request as ready for review February 20, 2026 04:45
Copy link
Member

@Jonathing Jonathing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No complaints from me. As we are the only consumer, we can patch things up later if need be. Nothing sticking out to me, so once this is good to go, go ahead and squash.

@LexManos LexManos merged commit dc417e7 into MinecraftForge:FD_7.0 Feb 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants